<?php
namespace App\Helpers;

use App\Helpers\Encrypt\EncryptFactory;
use Carbon\Carbon;
use Illuminate\Support\Facades\Hash;

class SelfEncrypt
{
    const MIX_STR = 'Iy/LCEH4ARKn5wCkCWJ4N7f19XqadKzRhGEvme7hew8=';
    const BASE_STR = '123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';

    /**
     * @title 加密字符串
     * @param string $str
     * @param array $options
     * @return mixed
     */
    public static function make(string $str,array $options = [])
    {
        $str = self::generateHashWithSalt($str);
        return  Hash::make($str,$options);
    }

    /**
     * @title 验证加密
     * @param $str
     * @param $pwd
     * @param array $options
     * @return mixed
     */
    public static function check($str,$pwd,array $options = [])
    {
        $str = self::generateHashWithSalt($str);
        return Hash::check($str,$pwd,$options);
    }

    /**
     * @title 密码附加盐值
     * @param $str
     * @return string
     */
    private static function generateHashWithSalt($str)
    {
        return  hash('sha512',sha1($str));
    }

    public static function createSalt($len = 16)
    {
        $key = substr(config('app.key'), 7);
        $key = $key?$key:md5(config('app.name',self::MIX_STR));
        $salt = str_shuffle($key);
        return substr($salt,rand(0,5),$len);
    }

    /**
     * 数据签名认证
     * @param  array $data 被认证的数据
     * @return string       签名
     */
    public static function dataAuthSign($data)
    {
        //数据类型检测
        if (!is_array($data)) {
            $data = (array)$data;
        }
        ksort($data); //排序
        $code = http_build_query($data); //url编码并生成query字符串
        $sign = sha1($code); //生成签名
        return $sign;
    }

    public static function randStr($length = 8,$str=false)
    {
        if(!$str){
            $str = self::BASE_STR;
        }
        $chars = str_shuffle(str_repeat($str, 5));
        $str = '';
        $end = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i++) {
            $str .= $chars[mt_rand(0,$end)];
        }
        return str_shuffle($str);
    }

    public static function createToken($len=24,$salt='yhf168')
    {
        $str = str_shuffle(self::randStr($len).md5($salt));
        $str_len = strlen($str);
        return substr($str,rand(0,$str_len-$len),$len);
    }

    public static function createCode($prefix='')
    {
        $date = Carbon::now();
        return strtoupper($prefix).$date->format('Ymd')
                .self::randStr(2,'ABCDEFGHJKLMNPQRSTUVWXYZ')
                .$date->format('His').self::randStr(4,'123456789');
    }

    public static function createSn($prefix,$length = 6)
    {
        return strtoupper($prefix).self::randStr($length,'123456789');
    }


    public static function encrypt($str,$token = '')
    {
        $cipher = EncryptFactory::factory(['token'=>$token])->encrypt($str);
        return $cipher?$cipher:$str;
    }

    public static function decrypt($cipher,$token = '')
    {
        $str = EncryptFactory::factory(['token'=>$token])->decrypt($cipher);
       return $str;
    }
}